﻿using Black.Surface2DEngine.Graphic2D;
using Black.Surface2DEngine.Graphic2D.Render2D;
using Black.Surface2DEngine.Graphic2D.Render2D.Extensions;
using Microsoft.Xna.Framework.Graphics;
using Black.Surface2DEngine.Input.Surface;
using Microsoft.Xna.Framework;
using Black.Surface2DEngine.Graphic2D.Render2D.Process2D;

namespace Black.Surface2DEngine.Test.Screens
{
    /// <summary>
    /// Ecran principal
    /// </summary>
    public class ProcessScreen : Screen
    {
        #region Variables d'instances

        private bool m_bAnimationStart;
        private Entity2DTexture m_oAnimObject;
        private Entity2DTexture m_oTouchOut;

        #endregion

        #region Fonctions protégées

        /// <summary>
        /// Charge les ressources
        /// </summary>
        protected override void LoadContent()
        {
            this.m_bAnimationStart = false;

            // Chargement des textures

            this.LoadRessource<Texture2D>("Wallpaper01");
            this.LoadRessource<SpriteFont>("MasterFont");
            this.LoadRessource<Texture2D>("LogoSurface01");
            this.LoadRessource<Texture2D>("Square");
        }

        /// <summary>
        /// Crée les objets logique
        /// </summary>
        protected override void LoadLogic()
        {
            Entity2DTexture oEntity;
            Entity2DText oText;

            // Création du fond

            oEntity = this.Entity2DCreate<Entity2DTexture>();
            oEntity.Texture = this.GetRessource<Texture2D>("Wallpaper01");

            // Création texte "Touch to start"

            oText = this.Entity2DCreate<Entity2DText>(200, 100);
            oText.SetAlign(Entity2DAlignHoriz.Center, Entity2DAlignVert.Center);
            oText.Text = "Touch to start";
            oText.Font = this.GetRessource<SpriteFont>("MasterFont");
            oText.Color = Color.White;

            // Effet sur le texte

            oText.Fade(-150, 500, true, true, null);

            // Création de l'objet a animer

            this.m_oAnimObject = this.Entity2DCreate<Entity2DTexture>(200, 200);
            this.m_oAnimObject.SetAlign(Entity2DAlignHoriz.Center, Entity2DAlignVert.Center);
            this.m_oAnimObject.Texture = this.GetRessource<Texture2D>("LogoSurface01");
            this.m_oAnimObject.Scale = 0.4f;

            // Création zone de sortie

            this.m_oTouchOut = this.Entity2DCreate<Entity2DTexture>(this.Graphic.ScreenWidth - 10, 10);
            this.m_oTouchOut.Texture = this.GetRessource<Texture2D>("Square");
            this.m_oTouchOut.SetAlign(Entity2DAlignHoriz.Right, Entity2DAlignVert.Top);

            oText = this.Entity2DCreate<Entity2DText>(this.Graphic.ScreenWidth - 65, 120);
            oText.SetAlign(Entity2DAlignHoriz.Right, Entity2DAlignVert.Top);
            oText.Text = "Touch to return";
            oText.Font = this.GetRessource<SpriteFont>("MasterFont");
            oText.Color = Color.Black;
        }

        /// <summary>
        /// Met à jour la logique de traitement de l'écran
        /// </summary>
        /// <param name="p_fTime">Indicateur temporel</param>
        protected override void UpdateOpen(float p_fTime)
        {
            // Recherche d'un contact sur une des zones

            foreach (TouchContact oContact in TouchManager._ContactsNew)
            {
                Rectangle oRect = new Rectangle((int)oContact.Contact.X, (int)oContact.Contact.Y, 2, 2);

                if (!this.m_bAnimationStart && this.m_oAnimObject.Zone.Contains(oRect))
                {
                    this.m_bAnimationStart = true;
                    this.CreateAndStartAnimation();
                }
                else if (this.m_oTouchOut.Zone.Contains(oRect))
                {
                    this.Graphic.CreateScreen<MasterScreen>(true);
                    this.Close();
                }
            }
        }

        #endregion

        #region Fonctions privées

        /// <summary>
        /// Crée et démare l'animation du logo Surface
        /// </summary>
        private void CreateAndStartAnimation()
        {
            // Création du process root pour la première transformation
            // On passe par les méthodes d'extensions pour le faire,
            // c'est une des deux méthodes, l'autre consiste a créer
            // son process et et de faire un this.Process2DStart()

            Process2DTranslation oProcessRoot = this.m_oAnimObject.Translation(new Vector2(250.0f, 250.0f), 3000.0f, false, false, null);

            // Utilisation de la propriété Next qui permet de définir les
            // prochaines transformation a la fin du process root.
            // Cette propriété est sur chaque Process2D et permet de faire 
            // un enchainement de transformation

            Process2DRotate oProcess01 = new Process2DRotate(this.m_oAnimObject, 360.0f, 3000, false, false, null);
            oProcessRoot.Next.Add(oProcess01);

            // Création d'un suite

            Process2DScale oProcess02 = new Process2DScale(this.m_oAnimObject, -0.3f, 500.0f, true, true, 6);
            Process2DTranslation oProcess03 = new Process2DTranslation(this.m_oAnimObject, new Vector2(-250.0f, -250.0f), 3000.0f, false, false, null);

            oProcess01.Next.Add(oProcess02);
            oProcess01.Next.Add(oProcess03);

            // On se branche sur un callback

            oProcess03.ProcessEnd += new System.EventHandler<Process2DArgs>(this.Process03_ProcessEnd);
        }

        /// <summary>
        /// Se produit sur la fin du process 03
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void Process03_ProcessEnd(object sender, Process2DArgs e)
        {
            this.m_bAnimationStart = false;
        }

        #endregion
    }
}
